﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using ReporterEngine;

namespace ReporterSystem
{
    public class ReportProject
    {
      
        
        public string Name;
        public Guid ProjectID;
        public NotebookInfo Notebook = new NotebookInfo();
        public List<ReportTemplate> Templates = new List<ReportTemplate>();

        public string EvalPath;

        public string ActualFilePath;

        public CIFModel ActualModel;//TODO update after notebook import



        public static ReportProject Load(string content)
        {
            var xSource = XDocument.Parse(content);
            ReportProject result = new ReportProject();

            var xProject = xSource.Root;

            result.Name = xProject.Element("ProjectName").Value;
            result.ProjectID = new Guid(xProject.Element("ProjectID").Value);
            result.EvalPath = GetString(xProject, "EvalPath");

            var xNotebook = xProject.Element("Notebook");

            result.Notebook.NotebookName = xNotebook.Element("NotebookName").Value;
            result.Notebook.LastImportDate = DateTime.Parse(xNotebook.Element("LastImportDate").Value);
            result.Notebook.ProvisionVersion = xNotebook.Element("ProvisionVersion").Value;
            result.Notebook.Updated = DateTime.Parse(xNotebook.Element("Updated").Value);

            var xTemplates = xProject.Element("Templates");

            foreach (var xTemplate in xTemplates.Elements("Template"))
            {
                var newTemplate = new ReportTemplate();

                newTemplate.TemplateFileName = xTemplate.Element("TemplateFileName").Value;
                newTemplate.TemplateFilePath = xTemplate.Element("TemplateFilePath").Value;
                newTemplate.ResultFileName = xTemplate.Element("ResultFileName").Value;
                newTemplate.ResultFilePath = xTemplate.Element("ResultFilePath").Value;
                newTemplate.ReportedDate = xTemplate.Element("ReportedDate")!=null && !string.IsNullOrEmpty(xTemplate.Element("ReportedDate").Value) ? (DateTime?)DateTime.Parse(xTemplate.Element("ReportedDate").Value) : null;
                newTemplate.ReportTemplateID = Guid.Parse(xTemplate.Element("ReportTemplateID").Value);
                newTemplate.AutoOpenResult = GetBool(xTemplate, "AutoOpenResult");
                          
                result.Templates.Add(newTemplate);

                var xParameters = xTemplate.Element("Parameters");

                if (xParameters != null)
                {
                    foreach (var xParameter in xParameters.Elements("Parameter"))
                    {
                        var newParameter = new TemplateParameter();
                        newParameter.ParameterName = GetString(xParameter, "ParameterName");
                        newParameter.Value = GetString(xParameter, "Value");

                        newTemplate.Parameters.Add(newParameter);
                    }
                }
            }
            
            return result;
        }

        public static string Save(ReportProject project)
        {
            var xResult = new XDocument();

            var xTemplates = new XElement("Templates");

            foreach (var tpl in project.Templates)
            {
                var xMessages = new XElement("Messages");

                foreach (var message in tpl.Messages)
                {
                    xMessages.Add(new XElement("Message",
                        new XElement("MessageText", message.Message),
                        new XElement("ExceptionMessage", message.ExceptionMessage)
                        ));
                }

                var xParameters = new XElement("Parameters");

                foreach (var parameter in tpl.Parameters)
                {
                    xParameters.Add(new XElement("Parameter",
                        new XElement("ParameterName", parameter.ParameterName),
                        new XElement("Value", parameter.Value)
                        ));
                }


                xTemplates.Add(new XElement("Template",
                             new XElement("TemplateFileName", tpl.TemplateFileName),
                             new XElement("TemplateFilePath", tpl.TemplateFilePath),
                             new XElement("ResultFileName", tpl.ResultFileName),
                             new XElement("ResultFilePath", tpl.ResultFilePath),
                             new XElement("ReportedDate", tpl.ReportedDate),
                             new XElement("ReportTemplateID", tpl.ReportTemplateID),
                             new XElement("AutoOpenResult", tpl.AutoOpenResult),
                             xMessages,
                             xParameters
                             ));



            }

            var root = new XElement("ReportProject",
                new XElement("ProjectName",project.Name),
                new XElement("ProjectID", project.ProjectID),
                new XElement("EvalPath", project.EvalPath),
                
                new XElement("Notebook",
                    new XElement("NotebookName",project.Notebook.NotebookName),
                    new XElement("LastImportDate", project.Notebook.LastImportDate),
                    new XElement("ProvisionVersion", project.Notebook.ProvisionVersion),
                    new XElement("Updated", project.Notebook.Updated)
                    )
                    ,
                    xTemplates    
                );

            xResult.Add(root);
            
            return xResult.ToString();
        }

        public static string GetString(XElement element,string elementName)
        {
            if (element.Element(elementName) != null)
            {
                return element.Element(elementName).Value;
            }
            
            return "";
        }

        public static bool GetBool(XElement element, string elementName)
        {
            if (element.Element(elementName) != null)
            {
                return bool.Parse(element.Element(elementName).Value);
            }

            return false;
        }
    }
}
